package com.zzj.service;

import com.zzj.base.Result;
import com.zzj.utils.JWTUtil;
import com.zzj.utils.RedisUtil;

import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Objects;

@Component
public class RedisService {
    @Resource
    private RedisUtil redisUtil;

    public static final String VERIFICATION_CODE_KEY = "PICC-VerificationCode";
    public static final String VERIFICATION_NUM_KEY = "PICC-VerificationNum";
    public static final long VERIFICATION_CODE_EXPIRATION_TIME = 5 * 60;  // 5 minutes
    public static final long VERIFICATION_CODE_DAY_NUM = 5; // Maximum number of verification code requests per day

    public static final String INVITATION_CODE_KEY = "PICC-InvitationCode";

    private final static String TOKEN = "PICC-Toekn";
    private final static String REFRESH_TOKEN = "PICC-RefreshToken";

    private final static String USERNAME = "PICC-Username";

    private final static String LIKE_HOSPITAL_ID = "PICC-LikeHospitalId";

    private final static String BOOK_SCHEDULE_ID = "PICC-BookScheduleId";

    private final static String LIKE_ARTICLE_ID = "PICC-LikeArticleId";

    private final static String CHAT_NO_READ_NUM = "PICC-ChatNoReadNum";


    private final static String REPLY_NO_READ_ID = "PICC-ReplyNoReadId";

    private final static String LIKE_NO_READ_ID = "PICC-LikeNoReadId";

    private final static String LIKE_COMMENT_ROOT_ID = "PICC-LikeCommentRootId";
    private final static String COMMENT_NO_READ_ID = "PICC_CommentNoReadId";
    private final static String NOTICE_READ_ID = "PICC_NoticeReadId";

    public String getNoticeReadId(String username) {
        return (String) redisUtil.hget(NOTICE_READ_ID, username);
    }

    public void setNoticeReadId(String username, String noticeReadId) {
        redisUtil.hset(NOTICE_READ_ID, username, noticeReadId);
    }

    public String getCommentNoReadId(String username) {
        return (String) redisUtil.hget(COMMENT_NO_READ_ID, username);
    }

    public void setCommentNoReadId(String username, String commentNoReadId) {
        redisUtil.hset(COMMENT_NO_READ_ID, username, commentNoReadId);
    }

    public String getLikeCommentRootId(String username) {
        return (String) redisUtil.hget(LIKE_COMMENT_ROOT_ID, username);
    }

    public void setLikeCommentRootId(String username, String likeCommentRootId) {
        redisUtil.hset(LIKE_COMMENT_ROOT_ID, username, likeCommentRootId);
    }

    public String getLikeNoReadId(String username) {
        return (String) redisUtil.hget(LIKE_NO_READ_ID, username);
    }

    public void removeLikeNoReadId(String username) {
        redisUtil.del(LIKE_NO_READ_ID, username);
    }

    public void setLikeNoReadId(String username, String likeNoReadId) {
        redisUtil.hset(LIKE_NO_READ_ID, username, likeNoReadId);
    }

    public String getReplyNoReadId(String username) {
        return (String) redisUtil.hget(REPLY_NO_READ_ID, username);
    }

    public void setReplyNoReadId(String username, String replyNoReadId) {
        redisUtil.hset(REPLY_NO_READ_ID, username, replyNoReadId);
    }


    public int getChatNoReadNum(String username) {
        Object hget = redisUtil.hget(CHAT_NO_READ_NUM, username);
        if(hget==null)return 0;
        return (int) hget;
    }

    public void setChatNoReadNum(String username, int num) {
        redisUtil.hset(CHAT_NO_READ_NUM, username, num);
    }

    public String getLikeArticleId(String username) {
        return (String) redisUtil.hget(LIKE_ARTICLE_ID, username);
    }

    public void setLikeArticleId(String username, String likeArticleId) {
        redisUtil.hset(LIKE_ARTICLE_ID, username, likeArticleId);
    }

    public String getBookScheduleId(String username) {
        return (String) redisUtil.hget(BOOK_SCHEDULE_ID, username);
    }

    public void setBookScheduleId(String username, String bookScheduleId) {
        redisUtil.hset(BOOK_SCHEDULE_ID, username, bookScheduleId);
    }

    public String getLikeHospitalId(String username) {
        return (String) redisUtil.hget(LIKE_HOSPITAL_ID, username);
    }

    public void setLikeHospitalId(String username, String likeHospitalId) {
        redisUtil.hset(LIKE_HOSPITAL_ID, username, likeHospitalId);
    }

    /**
     * 登录 token RefreshToken存储
     *
     * @param token
     * @param refreshToken
     * @param username
     */
    public void setRefreshToken(String token, String refreshToken, String username) {
        redisUtil.hset(refreshToken, TOKEN, token);
        redisUtil.hset(refreshToken, USERNAME, username);
        redisUtil.expire(refreshToken, JWTUtil.REFRESH_TOKEN_EXPIRE_TIME);
    }

    public void removeRefreshToken(String refreshToken) {
        redisUtil.del(refreshToken);
    }


    public String getUsername(String refreshToken) {
        return (String) redisUtil.hget(refreshToken, USERNAME);
    }

    public String getToken(String refreshToken) {
        return (String) redisUtil.hget(refreshToken, TOKEN);
    }


    public void createInvitation(String code, String type, int duration) {
        redisUtil.hset(INVITATION_CODE_KEY, code, type, (long) duration * 60 * 60);
    }

    public void removeInvitation(String code) {
        redisUtil.hdel(INVITATION_CODE_KEY, code);
    }

    public String getTypeByInvitationCode(String code) {
        return (String) redisUtil.hget(INVITATION_CODE_KEY, code);
    }

    /**
     * Verify the verification code and delete it if successful.
     *
     * @param email
     * @param code
     * @return
     */
    public Result verifyVerificationCode(String email, String code) {
        Object verificationCode = redisUtil.hget(VERIFICATION_CODE_KEY, email);
        if (verificationCode == null) {
            return Result.error("验证码失效或不存在");
        }
        if (!Objects.equals(code, String.valueOf(verificationCode))) {
            return Result.error("验证码错误");
        }
        redisUtil.hdel(VERIFICATION_CODE_KEY, email);
        return Result.success();
    }

    /**
     * Create a verification code that expires in 5 minutes.
     *
     * @param email
     * @param code
     * @return
     */
    public Result createVerificationCode(String email, String code) {
        Object verificationNum = redisUtil.hget(VERIFICATION_NUM_KEY, email);
        if (verificationNum != null && Integer.parseInt(String.valueOf(verificationNum)) >= VERIFICATION_CODE_DAY_NUM) {
            return Result.error("验证码今日发送次数已上线");
        }
        redisUtil.hset(VERIFICATION_NUM_KEY, email, verificationNum == null ? 1 : Integer.parseInt(String.valueOf(verificationNum)) + 1,
                getSecondsNextEarlyMorning());
        redisUtil.hset(VERIFICATION_CODE_KEY, email, code, VERIFICATION_CODE_EXPIRATION_TIME);
        return Result.success();
    }

    public boolean isInBlackList(String token) {
        return redisUtil.hHasKey(JWTUtil.BLACK_KEY, token);
    }


    /**
     * 到零点 多少秒
     * @return
     */
    public static  Long getSecondsNextEarlyMorning(){
        Calendar calendar=Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_YEAR,1);
        calendar.add(Calendar.HOUR_OF_DAY,0);
        calendar.add(Calendar.SECOND,0);
        calendar.add(Calendar.MINUTE,0);
        calendar.add(Calendar.MILLISECOND,0);
        return (calendar.getTimeInMillis()-System.currentTimeMillis())/1000;
    }

}
